const express = require("express");
const router = express.Router();
const { poolPromise } = require("../db/index");
// Token 生成器
const token_manager = require("../utils/jwt");

/**
 * 路由"/refresh/token" ---- 加入路由白名单 -- 单独校验
 *  需在请求headers中设置 Authorization: `Bearer ${refresh_token}`，登录成功时返回的 refresh_token。
 *  校验refresh token是否有效，无效则抛出Error/UnauthorizedError
 */
router.use(
  "/refresh/token",
  token_manager.guard([], async (req, token) => {
    console.log("refresh_token校验", token);
    let { type, jti } = token.payload;
    // 检测是否是 refresh_token
    if (type !== "refresh") throw Error("请在header中添加refresh_token!");

    // 检测refresh_token是否失效
    let select_sql = "select id, refresh_token from user where jwt_id = ?";
    let [result] = await poolPromise.query(select_sql, [jti]);
    // 查询结果为空 / refresh_token为空，皆为失效
    let isRevoked = !result[0]?.refresh_token;

    // refresh_token有效，在其payload中添加user_id、role_id等数据
    if (!isRevoked) token.payload = { ...token.payload, ...result[0] };

    return isRevoked;
  })
);

/**
 * 接收 refresh/token 的校验结果
 * 校验失败，抛出Error/UnauthorizedError，统一在此处理
 * 返回403状态码,返回错误信息
 */
router.use("/refresh/token", (err, req, res, next) => {
  // console.log(err.name, err.message, "token专门监听失败");
  if (err.name === "UnauthorizedError") {
    res.status(401).json({
      ...err,
      code: 401,
      msg: "刷新令牌失效,请重新登录！",
    });
  } else {
    next(err);
  }
});

/**
 * 刷新access_token
 *  refresh_token有效期大约30天，利用refresh_token重新换取一个有效期30分钟的access_token，如果refresh_token到期，返回403，强制用户重新登录。
 */
router.post("/refresh/token", async (req, res) => {
  let { user_id } = req.auth;
  // 生成payload
  let payload = { user_id };
  // 重新生成 access_token
  let access_token = token_manager.create_access_token({ ...payload, type: "access" });
  // 登录成功
  res.json({
    status: true,
    msg: "刷新成功！",
    code: 200,
    data: { access_token },
  });
});

module.exports = router;
